home *** CD-ROM | disk | FTP | other *** search
/ Revista CD Expert 8 / Revista CD Expert nº 08 CD1.iso / Utilitarios / Programacao / Bloodshed Dev-C++ 2.0 / _SETUP.1 / stl_slist.h < prev    next >
C/C++ Source or Header  |  1998-03-08  |  21KB  |  741 lines

  1. /*
  2.  * Copyright (c) 1997
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute and sell this software
  6.  * and its documentation for any purpose is hereby granted without fee,
  7.  * provided that the above copyright notice appear in all copies and
  8.  * that both that copyright notice and this permission notice appear
  9.  * in supporting documentation.  Silicon Graphics makes no
  10.  * representations about the suitability of this software for any
  11.  * purpose.  It is provided "as is" without express or implied warranty.
  12.  *
  13.  */
  14.  
  15. /* NOTE: This is an internal header file, included by other STL headers.
  16.  *   You should not attempt to use it directly.
  17.  */
  18.  
  19. #ifndef __SGI_STL_INTERNAL_SLIST_H
  20. #define __SGI_STL_INTERNAL_SLIST_H
  21.  
  22.  
  23. __STL_BEGIN_NAMESPACE 
  24.  
  25. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  26. #pragma set woff 1174
  27. #endif
  28.  
  29. struct __slist_node_base
  30. {
  31.   __slist_node_base* next;
  32. };
  33.  
  34. inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,
  35.                                             __slist_node_base* new_node)
  36. {
  37.   new_node->next = prev_node->next;
  38.   prev_node->next = new_node;
  39.   return new_node;
  40. }
  41.  
  42. inline __slist_node_base* __slist_previous(__slist_node_base* head,
  43.                                            const __slist_node_base* node)
  44. {
  45.   while (head && head->next != node)
  46.     head = head->next;
  47.   return head;
  48. }
  49.  
  50. inline const __slist_node_base* __slist_previous(const __slist_node_base* head,
  51.                                                  const __slist_node_base* node)
  52. {
  53.   while (head && head->next != node)
  54.     head = head->next;
  55.   return head;
  56. }
  57.  
  58. inline void __slist_splice_after(__slist_node_base* pos,
  59.                                  __slist_node_base* before_first,
  60.                                  __slist_node_base* before_last)
  61. {
  62.   if (pos != before_first && pos != before_last) {
  63.     __slist_node_base* first = before_first->next;
  64.     __slist_node_base* after = pos->next;
  65.     before_first->next = before_last->next;
  66.     pos->next = first;
  67.     before_last->next = after;
  68.   }
  69. }
  70.  
  71. inline __slist_node_base* __slist_reverse(__slist_node_base* node)
  72. {
  73.   __slist_node_base* result = node;
  74.   node = node->next;
  75.   result->next = 0;
  76.   while(node) {
  77.     __slist_node_base* next = node->next;
  78.     node->next = result;
  79.     result = node;
  80.     node = next;
  81.   }
  82.   return result;
  83. }
  84.  
  85. template <class T>
  86. struct __slist_node : public __slist_node_base
  87. {
  88.   T data;
  89. };
  90.  
  91. struct __slist_iterator_base
  92. {
  93.   typedef size_t size_type;
  94.   typedef ptrdiff_t difference_type;
  95.   typedef forward_iterator_tag iterator_category;
  96.  
  97.   __slist_node_base* node;
  98.  
  99.   __slist_iterator_base(__slist_node_base* x) : node(x) {}
  100.   void incr() { node = node->next; }
  101.  
  102.   bool operator==(const __slist_iterator_base& x) const {
  103.     return node == x.node;
  104.   }
  105.   bool operator!=(const __slist_iterator_base& x) const {
  106.     return node != x.node;
  107.   }
  108. };
  109.  
  110. template <class T, class Ref, class Ptr>
  111. struct __slist_iterator : public __slist_iterator_base
  112. {
  113.   typedef __slist_iterator<T, T&, T*>             iterator;
  114.   typedef __slist_iterator<T, const T&, const T*> const_iterator;
  115.   typedef __slist_iterator<T, Ref, Ptr>           self;
  116.  
  117.   typedef T value_type;
  118.   typedef Ptr pointer;
  119.   typedef Ref reference;
  120.   typedef __slist_node<T> list_node;
  121.  
  122.   __slist_iterator(list_node* x) : __slist_iterator_base(x) {}
  123.   __slist_iterator() : __slist_iterator_base(0) {}
  124.   __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}
  125.  
  126.   reference operator*() const { return ((list_node*) node)->data; }
  127. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  128.   pointer operator->() const { return &(operator*()); }
  129. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  130.  
  131.   self& operator++()
  132.   {
  133.     incr();
  134.     return *this;
  135.   }
  136.   self operator++(int)
  137.   {
  138.     self tmp = *this;
  139.     incr();
  140.     return tmp;
  141.   }
  142. };
  143.  
  144. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  145.  
  146. inline ptrdiff_t*
  147. distance_type(const __slist_iterator_base&)
  148. {
  149.   return 0;
  150. }
  151.  
  152. inline forward_iterator_tag
  153. iterator_category(const __slist_iterator_base&)
  154. {
  155.   return forward_iterator_tag();
  156. }
  157.  
  158. template <class T, class Ref, class Ptr> 
  159. inline T* 
  160. value_type(const __slist_iterator<T, Ref, Ptr>&) {
  161.   return 0;
  162. }
  163.  
  164. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  165.  
  166. inline size_t __slist_size(__slist_node_base* node)
  167. {
  168.   size_t result = 0;
  169.   for ( ; node != 0; node = node->next)
  170.     ++result;
  171.   return result;
  172. }
  173.  
  174. template <class T, class Alloc = alloc>
  175. class slist
  176. {
  177. public:
  178.   typedef T value_type;
  179.   typedef value_type* pointer;
  180.   typedef const value_type* const_pointer;
  181.   typedef value_type& reference;
  182.   typedef const value_type& const_reference;
  183.   typedef size_t size_type;
  184.   typedef ptrdiff_t difference_type;
  185.  
  186.   typedef __slist_iterator<T, T&, T*>             iterator;
  187.   typedef __slist_iterator<T, const T&, const T*> const_iterator;
  188.  
  189. private:
  190.   typedef __slist_node<T> list_node;
  191.   typedef __slist_node_base list_node_base;
  192.   typedef __slist_iterator_base iterator_base;
  193.   typedef simple_alloc<list_node, Alloc> list_node_allocator;
  194.  
  195.   static list_node* create_node(const value_type& x) {
  196.     list_node* node = list_node_allocator::allocate();
  197.     __STL_TRY {
  198.       construct(&node->data, x);
  199.       node->next = 0;
  200.     }
  201.     __STL_UNWIND(list_node_allocator::deallocate(node));
  202.     return node;
  203.   }
  204.   
  205.   static void destroy_node(list_node* node) {
  206.     destroy(&node->data);
  207.     list_node_allocator::deallocate(node);
  208.   }
  209.  
  210.   void fill_initialize(size_type n, const value_type& x) {
  211.     head.next = 0;
  212.     __STL_TRY {
  213.       _insert_after_fill(&head, n, x);
  214.     }
  215.     __STL_UNWIND(clear());
  216.   }    
  217.  
  218. #ifdef __STL_MEMBER_TEMPLATES
  219.   template <class InputIterator>
  220.   void range_initialize(InputIterator first, InputIterator last) {
  221.     head.next = 0;
  222.     __STL_TRY {
  223.       _insert_after_range(&head, first, last);
  224.     }
  225.     __STL_UNWIND(clear());
  226.   }
  227. #else /* __STL_MEMBER_TEMPLATES */
  228.   void range_initialize(const value_type* first, const value_type* last) {
  229.     head.next = 0;
  230.     __STL_TRY {
  231.       _insert_after_range(&head, first, last);
  232.     }
  233.     __STL_UNWIND(clear());
  234.   }
  235.   void range_initialize(const_iterator first, const_iterator last) {
  236.     head.next = 0;
  237.     __STL_TRY {
  238.       _insert_after_range(&head, first, last);
  239.     }
  240.     __STL_UNWIND(clear());
  241.   }
  242. #endif /* __STL_MEMBER_TEMPLATES */
  243.  
  244. private:
  245.   list_node_base head;
  246.  
  247. public:
  248.   slist() { head.next = 0; }
  249.  
  250.   slist(size_type n, const value_type& x) { fill_initialize(n, x); }
  251.   slist(int n, const value_type& x) { fill_initialize(n, x); }
  252.   slist(long n, const value_type& x) { fill_initialize(n, x); }
  253.   explicit slist(size_type n) { fill_initialize(n, value_type()); }
  254.  
  255. #ifdef __STL_MEMBER_TEMPLATES
  256.   template <class InputIterator>
  257.   slist(InputIterator first, InputIterator last) {
  258.     range_initialize(first, last);
  259.   }
  260.  
  261. #else /* __STL_MEMBER_TEMPLATES */
  262.   slist(const_iterator first, const_iterator last) {
  263.     range_initialize(first, last);
  264.   }
  265.   slist(const value_type* first, const value_type* last) {
  266.     range_initialize(first, last);
  267.   }
  268. #endif /* __STL_MEMBER_TEMPLATES */
  269.  
  270.   slist(const slist& L) { range_initialize(L.begin(), L.end()); }
  271.  
  272.   slist& operator= (const slist& L);
  273.  
  274.   ~slist() { clear(); }
  275.  
  276. public:
  277.  
  278.   iterator begin() { return iterator((list_node*)head.next); }
  279.   const_iterator begin() const { return const_iterator((list_node*)head.next);}
  280.  
  281.   iterator end() { return iterator(0); }
  282.   const_iterator end() const { return const_iterator(0); }
  283.  
  284.   size_type size() const { return __slist_size(head.next); }
  285.   
  286.   size_type max_size() const { return size_type(-1); }
  287.  
  288.   bool empty() const { return head.next == 0; }
  289.  
  290.   void swap(slist& L)
  291.   {
  292.     list_node_base* tmp = head.next;
  293.     head.next = L.head.next;
  294.     L.head.next = tmp;
  295.   }
  296.  
  297. public:
  298.   friend bool operator== __STL_NULL_TMPL_ARGS(const slist<T, Alloc>& L1,
  299.                                               const slist<T, Alloc>& L2);
  300.  
  301. public:
  302.  
  303.   reference front() { return ((list_node*) head.next)->data; }
  304.   const_reference front() const { return ((list_node*) head.next)->data; }
  305.   void push_front(const value_type& x)   {
  306.     __slist_make_link(&head, create_node(x));
  307.   }
  308.   void pop_front() {
  309.     list_node* node = (list_node*) head.next;
  310.     head.next = node->next;
  311.     destroy_node(node);
  312.   }
  313.  
  314.   iterator previous(const_iterator pos) {
  315.     return iterator((list_node*) __slist_previous(&head, pos.node));
  316.   }
  317.   const_iterator previous(const_iterator pos) const {
  318.     return const_iterator((list_node*) __slist_previous(&head, pos.node));
  319.   }
  320.  
  321. private:
  322.   list_node* _insert_after(list_node_base* pos, const value_type& x) {
  323.     return (list_node*) (__slist_make_link(pos, create_node(x)));
  324.   }
  325.  
  326.   void _insert_after_fill(list_node_base* pos,
  327.                           size_type n, const value_type& x) {
  328.     for (size_type i = 0; i < n; ++i)
  329.       pos = __slist_make_link(pos, create_node(x));
  330.   }
  331.  
  332. #ifdef __STL_MEMBER_TEMPLATES
  333.   template <class InIter>
  334.   void _insert_after_range(list_node_base* pos, InIter first, InIter last) {
  335.     while (first != last) {
  336.       pos = __slist_make_link(pos, create_node(*first));
  337.       ++first;
  338.     }
  339.   }
  340. #else /* __STL_MEMBER_TEMPLATES */
  341.   void _insert_after_range(list_node_base* pos,
  342.                            const_iterator first, const_iterator last) {
  343.     while (first != last) {
  344.       pos = __slist_make_link(pos, create_node(*first));
  345.       ++first;
  346.     }
  347.   }
  348.   void _insert_after_range(list_node_base* pos,
  349.                            const value_type* first, const value_type* last) {
  350.     while (first != last) {
  351.       pos = __slist_make_link(pos, create_node(*first));
  352.       ++first;
  353.     }
  354.   }
  355. #endif /* __STL_MEMBER_TEMPLATES */
  356.  
  357.   list_node_base* erase_after(list_node_base* pos) {
  358.     list_node* next = (list_node*) (pos->next);
  359.     list_node_base* next_next = next->next;
  360.     pos->next = next_next;
  361.     destroy_node(next);
  362.     return next_next;
  363.   }
  364.    
  365.   list_node_base* erase_after(list_node_base* before_first,
  366.                               list_node_base* last_node) {
  367.     list_node* cur = (list_node*) (before_first->next);
  368.     while (cur != last_node) {
  369.       list_node* tmp = cur;
  370.       cur = (list_node*) cur->next;
  371.       destroy_node(tmp);
  372.     }
  373.     before_first->next = last_node;
  374.     return last_node;
  375.   }
  376.  
  377.  
  378. public:
  379.  
  380.   iterator insert_after(iterator pos, const value_type& x) {
  381.     return iterator(_insert_after(pos.node, x));
  382.   }
  383.  
  384.   iterator insert_after(iterator pos) {
  385.     return insert_after(pos, value_type());
  386.   }
  387.  
  388.   void insert_after(iterator pos, size_type n, const value_type& x) {
  389.     _insert_after_fill(pos.node, n, x);
  390.   }
  391.   void insert_after(iterator pos, int n, const value_type& x) {
  392.     _insert_after_fill(pos.node, (size_type) n, x);
  393.   }
  394.   void insert_after(iterator pos, long n, const value_type& x) {
  395.     _insert_after_fill(pos.node, (size_type) n, x);
  396.   }
  397.  
  398. #ifdef __STL_MEMBER_TEMPLATES
  399.   template <class InIter>
  400.   void insert_after(iterator pos, InIter first, InIter last) {
  401.     _insert_after_range(pos.node, first, last);
  402.   }
  403. #else /* __STL_MEMBER_TEMPLATES */
  404.   void insert_after(iterator pos, const_iterator first, const_iterator last) {
  405.     _insert_after_range(pos.node, first, last);
  406.   }
  407.   void insert_after(iterator pos,
  408.                     const value_type* first, const value_type* last) {
  409.     _insert_after_range(pos.node, first, last);
  410.   }
  411. #endif /* __STL_MEMBER_TEMPLATES */
  412.  
  413.   iterator insert(iterator pos, const value_type& x) {
  414.     return iterator(_insert_after(__slist_previous(&head, pos.node), x));
  415.   }
  416.  
  417.   iterator insert(iterator pos) {
  418.     return iterator(_insert_after(__slist_previous(&head, pos.node),
  419.                                   value_type()));
  420.   }
  421.  
  422.   void insert(iterator pos, size_type n, const value_type& x) {
  423.     _insert_after_fill(__slist_previous(&head, pos.node), n, x);
  424.   } 
  425.   void insert(iterator pos, int n, const value_type& x) {
  426.     _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
  427.   } 
  428.   void insert(iterator pos, long n, const value_type& x) {
  429.     _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
  430.   } 
  431.     
  432. #ifdef __STL_MEMBER_TEMPLATES
  433.   template <class InIter>
  434.   void insert(iterator pos, InIter first, InIter last) {
  435.     _insert_after_range(__slist_previous(&head, pos.node), first, last);
  436.   }
  437. #else /* __STL_MEMBER_TEMPLATES */
  438.   void insert(iterator pos, const_iterator first, const_iterator last) {
  439.     _insert_after_range(__slist_previous(&head, pos.node), first, last);
  440.   }
  441.   void insert(iterator pos, const value_type* first, const value_type* last) {
  442.     _insert_after_range(__slist_previous(&head, pos.node), first, last);
  443.   }
  444. #endif /* __STL_MEMBER_TEMPLATES */
  445.  
  446.  
  447. public:
  448.   iterator erase_after(iterator pos) {
  449.     return iterator((list_node*)erase_after(pos.node));
  450.   }
  451.   iterator erase_after(iterator before_first, iterator last) {
  452.     return iterator((list_node*)erase_after(before_first.node, last.node));
  453.   }
  454.  
  455.   iterator erase(iterator pos) {
  456.     return (list_node*) erase_after(__slist_previous(&head, pos.node));
  457.   }
  458.   iterator erase(iterator first, iterator last) {
  459.     return (list_node*) erase_after(__slist_previous(&head, first.node),
  460.                                     last.node);
  461.   }
  462.  
  463.   void resize(size_type new_size, const T& x);
  464.   void resize(size_type new_size) { resize(new_size, T()); }
  465.   void clear() { erase_after(&head, 0); }
  466.  
  467. public:
  468.   // Moves the range [before_first + 1, before_last + 1) to *this,
  469.   //  inserting it immediately after pos.  This is constant time.
  470.   void splice_after(iterator pos, 
  471.                     iterator before_first, iterator before_last)
  472.   {
  473.     if (before_first != before_last) 
  474.       __slist_splice_after(pos.node, before_first.node, before_last.node);
  475.   }
  476.  
  477.   // Moves the element that follows prev to *this, inserting it immediately
  478.   //  after pos.  This is constant time.
  479.   void splice_after(iterator pos, iterator prev)
  480.   {
  481.     __slist_splice_after(pos.node, prev.node, prev.node->next);
  482.   }
  483.  
  484.  
  485.   // Linear in distance(begin(), pos), and linear in L.size().
  486.   void splice(iterator pos, slist& L) {
  487.     if (L.head.next)
  488.       __slist_splice_after(__slist_previous(&head, pos.node),
  489.                            &L.head,
  490.                            __slist_previous(&L.head, 0));
  491.   }
  492.  
  493.   // Linear in distance(begin(), pos), and in distance(L.begin(), i).
  494.   void splice(iterator pos, slist& L, iterator i) {
  495.     __slist_splice_after(__slist_previous(&head, pos.node),
  496.                          __slist_previous(&L.head, i.node),
  497.                          i.node);
  498.   }
  499.  
  500.   // Linear in distance(begin(), pos), in distance(L.begin(), first),
  501.   // and in distance(first, last).
  502.   void splice(iterator pos, slist& L, iterator first, iterator last)
  503.   {
  504.     if (first != last)
  505.       __slist_splice_after(__slist_previous(&head, pos.node),
  506.                            __slist_previous(&L.head, first.node),
  507.                            __slist_previous(first.node, last.node));
  508.   }
  509.  
  510. public:
  511.   void reverse() { if (head.next) head.next = __slist_reverse(head.next); }
  512.  
  513.   void remove(const T& val); 
  514.   void unique(); 
  515.   void merge(slist& L);
  516.   void sort();     
  517.  
  518. #ifdef __STL_MEMBER_TEMPLATES
  519.   template <class Predicate> void remove_if(Predicate pred);
  520.   template <class BinaryPredicate> void unique(BinaryPredicate pred); 
  521.   template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering); 
  522.   template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp); 
  523. #endif /* __STL_MEMBER_TEMPLATES */
  524. };
  525.  
  526. template <class T, class Alloc>
  527. slist<T, Alloc>& slist<T,Alloc>::operator=(const slist<T, Alloc>& L)
  528. {
  529.   if (&L != this) {
  530.     list_node_base* p1 = &head;
  531.     list_node* n1 = (list_node*) head.next;
  532.     const list_node* n2 = (const list_node*) L.head.next;
  533.     while (n1 && n2) {
  534.       n1->data = n2->data;
  535.       p1 = n1;
  536.       n1 = (list_node*) n1->next;
  537.       n2 = (const list_node*) n2->next;
  538.     }
  539.     if (n2 == 0)
  540.       erase_after(p1, 0);
  541.     else
  542.       _insert_after_range(p1,
  543.                           const_iterator((list_node*)n2), const_iterator(0));
  544.   }
  545.   return *this;
  546.  
  547. template <class T, class Alloc>
  548. bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
  549. {
  550.   typedef typename slist<T,Alloc>::list_node list_node;
  551.   list_node* n1 = (list_node*) L1.head.next;
  552.   list_node* n2 = (list_node*) L2.head.next;
  553.   while (n1 && n2 && n1->data == n2->data) {
  554.     n1 = (list_node*) n1->next;
  555.     n2 = (list_node*) n2->next;
  556.   }
  557.   return n1 == 0 && n2 == 0;
  558. }
  559.  
  560. template <class T, class Alloc>
  561. inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
  562. {
  563.   return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end());
  564. }
  565.  
  566. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  567.  
  568. template <class T, class Alloc>
  569. inline void swap(slist<T, Alloc>& x, slist<T, Alloc>& y) {
  570.   x.swap(y);
  571. }
  572.  
  573. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  574.  
  575.  
  576. template <class T, class Alloc>
  577. void slist<T, Alloc>::resize(size_type len, const T& x)
  578. {
  579.   list_node_base* cur = &head;
  580.   while (cur->next != 0 && len > 0) {
  581.     --len;
  582.     cur = cur->next;
  583.   }
  584.   if (cur->next) 
  585.     erase_after(cur, 0);
  586.   else
  587.     _insert_after_fill(cur, len, x);
  588. }
  589.  
  590. template <class T, class Alloc>
  591. void slist<T,Alloc>::remove(const T& val)
  592. {
  593.   list_node_base* cur = &head;
  594.   while (cur && cur->next) {
  595.     if (((list_node*) cur->next)->data == val)
  596.       erase_after(cur);
  597.     else
  598.       cur = cur->next;
  599.   }
  600. }
  601.  
  602. template <class T, class Alloc> 
  603. void slist<T,Alloc>::unique()
  604. {
  605.   list_node_base* cur = head.next;
  606.   if (cur) {
  607.     while (cur->next) {
  608.       if (((list_node*)cur)->data == ((list_node*)(cur->next))->data)
  609.         erase_after(cur);
  610.       else
  611.         cur = cur->next;
  612.     }
  613.   }
  614. }
  615.  
  616. template <class T, class Alloc>
  617. void slist<T,Alloc>::merge(slist<T,Alloc>& L)
  618. {
  619.   list_node_base* n1 = &head;
  620.   while (n1->next && L.head.next) {
  621.     if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data) 
  622.       __slist_splice_after(n1, &L.head, L.head.next);
  623.     n1 = n1->next;
  624.   }
  625.   if (L.head.next) {
  626.     n1->next = L.head.next;
  627.     L.head.next = 0;
  628.   }
  629. }
  630.  
  631. template <class T, class Alloc>
  632. void slist<T,Alloc>::sort()
  633. {
  634.   if (head.next && head.next->next) {
  635.     slist carry;
  636.     slist counter[64];
  637.     int fill = 0;
  638.     while (!empty()) {
  639.       __slist_splice_after(&carry.head, &head, head.next);
  640.       int i = 0;
  641.       while (i < fill && !counter[i].empty()) {
  642.         counter[i].merge(carry);
  643.         carry.swap(counter[i]);
  644.         ++i;
  645.       }
  646.       carry.swap(counter[i]);
  647.       if (i == fill)
  648.         ++fill;
  649.     }
  650.  
  651.     for (int i = 1; i < fill; ++i)
  652.       counter[i].merge(counter[i-1]);
  653.     this->swap(counter[fill-1]);
  654.   }
  655. }
  656.  
  657. #ifdef __STL_MEMBER_TEMPLATES
  658.  
  659. template <class T, class Alloc> 
  660. template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred)
  661. {
  662.   list_node_base* cur = &head;
  663.   while (cur->next) {
  664.     if (pred(((list_node*) cur->next)->data))
  665.       erase_after(cur);
  666.     else
  667.       cur = cur->next;
  668.   }
  669. }
  670.  
  671. template <class T, class Alloc> template <class BinaryPredicate> 
  672. void slist<T,Alloc>::unique(BinaryPredicate pred)
  673. {
  674.   list_node* cur = (list_node*) head.next;
  675.   if (cur) {
  676.     while (cur->next) {
  677.       if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data))
  678.         erase_after(cur);
  679.       else
  680.         cur = (list_node*) cur->next;
  681.     }
  682.   }
  683. }
  684.  
  685. template <class T, class Alloc> template <class StrictWeakOrdering>
  686. void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp)
  687. {
  688.   list_node_base* n1 = &head;
  689.   while (n1->next && L.head.next) {
  690.     if (comp(((list_node*) L.head.next)->data,
  691.              ((list_node*) n1->next)->data))
  692.       __slist_splice_after(n1, &L.head, L.head.next);
  693.     n1 = n1->next;
  694.   }
  695.   if (L.head.next) {
  696.     n1->next = L.head.next;
  697.     L.head.next = 0;
  698.   }
  699. }
  700.  
  701. template <class T, class Alloc> template <class StrictWeakOrdering> 
  702. void slist<T,Alloc>::sort(StrictWeakOrdering comp)
  703. {
  704.   if (head.next && head.next->next) {
  705.     slist carry;
  706.     slist counter[64];
  707.     int fill = 0;
  708.     while (!empty()) {
  709.       __slist_splice_after(&carry.head, &head, head.next);
  710.       int i = 0;
  711.       while (i < fill && !counter[i].empty()) {
  712.         counter[i].merge(carry, comp);
  713.         carry.swap(counter[i]);
  714.         ++i;
  715.       }
  716.       carry.swap(counter[i]);
  717.       if (i == fill)
  718.         ++fill;
  719.     }
  720.  
  721.     for (int i = 1; i < fill; ++i)
  722.       counter[i].merge(counter[i-1], comp);
  723.     this->swap(counter[fill-1]);
  724.   }
  725. }
  726.  
  727. #endif /* __STL_MEMBER_TEMPLATES */
  728.  
  729. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  730. #pragma reset woff 1174
  731. #endif
  732.  
  733. __STL_END_NAMESPACE 
  734.  
  735. #endif /* __SGI_STL_INTERNAL_SLIST_H */
  736.  
  737. // Local Variables:
  738. // mode:C++
  739. // End:
  740.